/*
    说明：
    1: JSON.stringfy --> set --> get --> JSON.parse
    2: data format well return as set`s
    3: undefined in array will be null after stringfy+parse
    4: NS --> namespace 缩写
    */
let keyNS = 'epointcache-';
class Cache {



    hasOwnProperty(target, key) {
        return Object.prototype.hasOwnProperty.call(target, key);
    }

    isKeyExist(key) {
        // do not depend on value cause of ""和0
        return this.hasOwnProperty(localStorage, key) || this.hasOwnProperty(sessionStorage, key);
    }

    get(key) {
            /*
           legal data: "" [] {} null flase true
    
           illegal: undefined
               1: key not set
               2: key is cleared
               3: key removed
               4: wrong data format
           */
            const tempKey = keyNS + key;
            if (!this.isKeyExist(tempKey)) {
                return undefined;
            }
            // maybe keyNS could avoid conflict
            let val = localStorage.getItem(tempKey) || sessionStorage.getItem(tempKey);
            val = JSON.parse(val);
            // val format check
            if (val !== null && this.hasOwnProperty(val, 'type') && this.hasOwnProperty(val, 'data')) {
                return val.data;
            }
            /*
               how to return illegal data for im？
               */
            return undefined;
        }
        // isPersistent
    set(key, val, isTemp) {
        let store = localStorage;
        if (isTemp) {
            store = sessionStorage;
        }
        const type = (typeof val);
        store[keyNS + key] = JSON.stringify({
            data: val,
            type,
        });
    }

    remove(key) {
        const key1 = keyNS + key;
        localStorage.removeItem(key1);
        sessionStorage.removeItem(key1);
    }

    setKeyNS(NS) {
        if (isString(NS) && NS !== '') {
            keyNS = NS;
        }
    }

    onchange(callback) {
        $(window).on('storage', (e) => {
            const event = e.originalEvent;
            if (isEmpty(event.key)) {
                return;
            }
            const key = event.key.slice(keyNS.length);
            const value = get(key);
            if (callback) {
                callback(key, value);
            }
        });
    }

    isString(str) {
        return Object.prototype.toString.call(str) === '[object String]';
    }

    isEmpty(value) {
        let undef;
        const list = [null, undef, ''];
        return list.indexOf(value) >= 0;
    }
}


module.exports = new Cache();